#include "wificonfigg.h"

WiFiConfigurator::WiFiConfigurator(IPAddress localIP, IPAddress gateway, IPAddress subnet)
    : server(80), localIP(localIP), gateway(gateway), subnet(subnet) {}

void WiFiConfigurator::begin(){
  Serial.begin(115200);
  prefs.begin("wifi", true);
  String ssid = prefs.getString("ssid", "");
  String pass = prefs.getString("pass", "");
  prefs.end();
  if (!ssid.isEmpty()) {
      connectWiFi(ssid, pass, 15);
  }
  startAP();
  setupServer();
  if (WiFi.status() != WL_CONNECTED) {
      startAP();
  } else {
      Serial.print("STA mode access to Address: ");
      Serial.println(WiFi.localIP());
  }  
}

void WiFiConfigurator::loop() {
    server.handleClient();
}

bool WiFiConfigurator::connectWiFi(String ssid, String pass, int timeout){
  WiFi.begin(ssid.c_str(), pass.c_str());
    Serial.print("Connecting to ");
    Serial.println(ssid);
    for (int i = 0; i < timeout; i++) {
        if (WiFi.status() == WL_CONNECTED) {
            Serial.println("\nConnected!");
            Serial.print("IP: ");
            Serial.println(WiFi.localIP());
            return true;
        }
        delay(1000);
        Serial.print(".");
    }
  Serial.println("\nTimeout!");
  return false;
}

void WiFiConfigurator::startAP() {
  Serial.print("\r\nStart ap");
  WiFi.mode(WIFI_AP_STA);
  delay(100);
  WiFi.setTxPower(WIFI_POWER_20dBm);
  WiFi.softAPConfig(localIP, gateway, subnet);
  WiFi.softAP("ESP32-Setup", "123456789", 6, false, 4);
  Serial.print("AP IP: ");
  Serial.println(WiFi.softAPIP());
}

void WiFiConfigurator::setupServer() {
    server.on("/scan", HTTP_GET, [this]() {
        server.send(200, "application/json", scanNetworks());
    });

    server.on("/", HTTP_GET, [this]() {
        server.send(200, "text/html", getHTMLPage());
    });

    server.on("/connect", HTTP_POST, [this]() {
        String ssid = server.arg("ssid");
        String pass = server.arg("pass");
        String result;
        if (ssid.isEmpty()) {
            result = "<div class='error result'>必须输入WiFi名称</div>";
            server.send(200, "text/html", result);
            return;
        }
        if (connectWiFi(ssid, pass, 20)) {
            prefs.begin("wifi", false);
            prefs.putString("ssid", ssid);
            prefs.putString("pass", pass);
            prefs.end();
            result = "<div class='success result'>"
                      "<h2>✅ 连接成功！</h2>"
                      "<p>WiFi名称: " + ssid + "</p>"
                      "<p>IP地址：" + WiFi.localIP().toString() + "</p>"
                      "<p>设备已上线</p></div>";
        } else {
            result = "<div class='error result'>连接失败，请检查密码和信号强度</div>";
        }
        server.send(200, "text/html", result);
    });

    // server.on("/clear", HTTP_GET, [this]() {
    //     prefs.begin("wifi", false);
    //     prefs.remove("ssid");
    //     prefs.remove("pass");
    //     prefs.end();
    //     server.send(200, "text/html", "<div class='success result'>WiFi历史配置已清楚,开发板重启后需重新配置WiFi</div>");
    // });

    server.begin();
}

String WiFiConfigurator::scanNetworks() {
    WiFi.mode(WIFI_AP_STA);
    delay(100);
    int n = WiFi.scanNetworks();
    WiFi.mode(WIFI_AP_STA);
    DynamicJsonDocument doc(1024);
    for (int i = 0; i < n; ++i) {
        JsonObject network = doc.createNestedObject();
        network["ssid"] = WiFi.SSID(i);
        network["rssi"] = WiFi.RSSI(i);
        network["encrypted"] = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
    }
    String result;
    serializeJson(doc, result);
    WiFi.scanDelete();
    return result;
}

String WiFiConfigurator::getHTMLPage() {
    return F(
        "<!DOCTYPE html>"
        "<html lang='zh'>"
        "<head>"
        "<meta charset='UTF-8'>"
        "<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
        "<title>ESP32配网</title>"
        "<style>"
        "* { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', sans-serif; }"
        "body { background: #f0f2f5; min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; }"
        ".container { background: white; border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); padding: 2rem; width: 100%; max-width: 400px; }"
        "h1 { color: #2d3436; text-align: center; margin-bottom: 1.5rem; font-size: 1.8rem; }"
        ".form-group { margin-bottom: 1.2rem; }"
        "label { display: block; color: #636e72; margin-bottom: 0.5rem; font-weight: 500; }"
        "input { width: 100%; padding: 0.8rem; border: 2px solid #dfe6e9; border-radius: 8px; font-size: 1rem; transition: border-color 0.3s ease; }"
        "input:focus { outline: none; border-color: #6c5ce7; }"
        "button { width: 100%; background: #6c5ce7; color: white; padding: 1rem; border: none; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: background 0.3s ease; }"
        "button:hover { background: #5b4bc4; }"
        "button:disabled { background: #b0b0b0; cursor: not-allowed; }"
        ".result { padding: 1rem; border-radius: 8px; margin-top: 1rem; text-align: center; }"
        ".success { background: #e8f5e9; color: #2e7d32; }"
        ".error { background: #ffebee; color: #c62828; }"
        "a { display: inline-block; margin-top: 1rem; color: #6c5ce7; text-decoration: none; font-weight: 500; }"
        ".loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.9); display: none; justify-content: center; align-items: center; z-index: 1000; }"
        ".loading-spinner { width: 50px; height: 50px; border: 4px solid #f3f3f3; border-top: 4px solid #6c5ce7; border-radius: 50%; animation: spin 1s linear infinite; }"
        "@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }"
        ".scan-controls { margin-top: 1.5rem; }"
        ".wifi-list { max-height: 200px; overflow-y: auto; border: 1px solid #eee; border-radius: 8px; margin-top: 0.5rem; }"
        ".wifi-item { padding: 0.8rem; cursor: pointer; transition: background 0.2s; display: flex; justify-content: space-between; align-items: center; }"
        ".wifi-item:hover { background: #f8f9fa; }"
        ".signal { display: flex; gap: 2px; }"
        ".signal .bar { width: 4px; background: #ddd; border-radius: 2px; }"
        ".signal .bar.active { background: #6c5ce7; }"
        ".signal .bar:nth-child(1) { height: 5px; }"
        ".signal .bar:nth-child(2) { height: 10px; }"
        ".signal .bar:nth-child(3) { height: 15px; }"
        ".signal .bar:nth-child(4) { height: 20px; }"
        "</style>"
        "<script>"
        "let isScanning = false;"
        "function handleSubmit(e) {"
        "e.preventDefault();"
        "document.getElementById('loading').style.display = 'flex';"
        "const formData = new FormData(e.target);"
        "fetch('/connect', {"
        "method: 'POST',"
        "body: new URLSearchParams(formData)"
        "})"
        ".then(response => response.text())"
        ".then(html => {"
        "document.getElementById('result').innerHTML = html;"
        "})"
        ".catch(error => {"
        "document.getElementById('result').innerHTML = \"<div class='error result'>网络请求失败，请重试</div>\";"
        "})"
        ".finally(() => {"
        "document.getElementById('loading').style.display = 'none';"
        "});"
        "}"
        "function refreshList() {"
        "if (isScanning) return;"
        "isScanning = true;"
        "document.getElementById('loading').style.display = 'flex';"
        "const scanBtn = document.getElementById('scanBtn');"
        "scanBtn.disabled = true;"
        "scanBtn.innerHTML = '扫描中...';"
        "const list = document.getElementById('wifiList');"
        "list.innerHTML = '<div style=\"text-align: center; padding: 1rem;\">正在扫描...</div>';"
        "fetch('/scan')"
        ".then(r => r.json())"
        ".then(data => {"
        "list.innerHTML = '';"
        "if (data.length === 0) {"
        "list.innerHTML = '<div style=\"text-align: center; padding: 1rem;\">未找到WiFi网络</div>';"
        "return;"
        "}"
        "data.sort((a, b) => b.rssi - a.rssi);"
        "data.forEach(net => {"
        "const item = document.createElement('div');"
        "item.className = 'wifi-item';"
        "item.onclick = () => selectWifi(net.ssid);"
        "item.innerHTML = `"
        "<span>${net.ssid}</span>"
        "<div class='signal'>${getSignalBars(net.rssi)}</div>"
        "`;"
        "list.appendChild(item);"
        "});"
        "})"
        ".catch(() => {"
        "list.innerHTML = '<div style=\"text-align: center; padding: 1rem; color: #c62828;\">扫描失败，请重试</div>';"
        "})"
        ".finally(() => {"
        "isScanning = false;"
        "document.getElementById('loading').style.display = 'none';"
        "scanBtn.disabled = false;"
        "scanBtn.innerHTML = '刷新列表';"
        "});"
        "}"
        "function getSignalBars(rssi) {"
        "if (rssi > -70) {"
        "  return Array.from({length: 4}, () => '<div class=\"bar active\"></div>').join('');"
        "} else if (rssi > -80) {"
        "  return Array.from({length: 3}, () => '<div class=\"bar active\"></div>').concat(Array.from({length: 1}, () => '<div class=\"bar\"></div>')).join('');"
        "} else if (rssi > -90) {"
        "  return Array.from({length: 2}, () => '<div class=\"bar active\"></div>').concat(Array.from({length: 2}, () => '<div class=\"bar\"></div>')).join('');"
        "} else if (rssi > -100) {"
        "  return Array.from({length: 1}, () => '<div class=\"bar active\"></div>').concat(Array.from({length: 3}, () => '<div class=\"bar\"></div>')).join('');"
        "} else {"
        "  return Array.from({length: 4}, () => '<div class=\"bar\"></div>').join('');"
        "}"
        "}"
        "function selectWifi(ssid) {"
        "document.getElementById('ssid').value = ssid;"
        "document.getElementById('pass').focus();"
        "}"
        "</script>"
        "</head>"
        "<body>"
        "<div class='container'>"
        "<h1>WiFi 配置</h1>"
        "<div class='scan-controls'>"
        "<button id='scanBtn' type='button' onclick='refreshList()'>刷新列表</button>"
        "<div class='wifi-list' id='wifiList'></div>"
        "</div>"
        "<form onsubmit='handleSubmit(event)'>"
        "<div class='form-group'>"
        "<label for='ssid'>WiFi 名称</label>"
        "<input type='text' id='ssid' name='ssid' placeholder='选择上方网络或手动输入' required>"
        "</div>"
        "<div class='form-group'>"
        "<label for='pass'>密码</label>"
        "<input type='password' id='pass' name='pass' placeholder='输入密码'>"
        "</div>"
        "<button type='submit'>立即连接</button>"
        "</form>"
        // "<a href='/clear' onclick='return confirm(\"确定要清除WiFi配置吗\")'>清除已保存配置</a>"
        "<div id='result'></div>"
        "</div>"
        "<div id='loading' class='loading-overlay'>"
        "<div class='loading-spinner'></div>"
        "</div>"
        "</body>"
        "</html>"
    );
}